package com.sunseaypw.db.trans;

import java.io.IOException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

public class SpringTrans {
    public static void main(String[] args){
        ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("springTrans.xml");
        var st=ctx.getBean(StudentDAO.class);
        st.dbOperate1();

        var ud=ctx.getBean(UserDAO.class);
        ud.dbOperate1();
    }    
    public static class UserDAO{  
        JdbcTemplate jt;
        public UserDAO(JdbcTemplate jt){
            this.jt=jt;
        }
        public void dbOperate1(){
            //异常后自动回滚
            jt.execute("update students set name='第111111111111111次更新' where id=9 ");
            jt.execute("update students set name2222='第222222222222222次更新' where id=9");
            //自动提交
        }
    }  
    
    public static class StudentDAO{  
        @Autowired
        JdbcTemplate jt;  
        /*只能被应用到public方法上, 对于其它非public的方法,如果标记了@Transactional也不会报错,但方法没有事务功能. 
            用 spring 事务管理器,由spring来负责数据库的打开,提交,回滚.默认遇到运行期例外(throw new RuntimeException("注释");)会回滚，即遇到不受检查（unchecked）的例外时回滚；
            而遇到需要捕获的例外(throw new Exception("注释");)不会回滚,即遇到受检查的例外
            （就是非运行时抛出的异常，编译器会检查到的异常叫受检查例外或说受检查异常）时，
            需我们指定方式来让事务回滚 要想所有异常都回滚,要加上 @Transactional( rollbackFor={Exception.class,其它异常}) .
            如果让unchecked例外不回滚： @Transactional(notRollbackFor=RunTimeException.class)        
        */
        @Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED
            ,rollbackFor = IOException.class )   //是rollback 非checked运行时异常是默认的，只能采用noRollbackfor禁用  
        public void dbOperate1(){
            //异常后自动回滚
            jt.execute("update students set name='第111111111111111次更新' where id=9 ");
            jt.execute("update students set name2222='第222222222222222次更新' where id=9");
            //自动提交
        }
    }    
}
